home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / printing / pnmtoprt.0 / pnmtoprt / pnmtoprt-2.0 / necp6.c < prev    next >
C/C++ Source or Header  |  1996-03-28  |  43KB  |  1,764 lines

  1. /* Driver for NEC P6 mono and color
  2.  */
  3.  
  4. #include <stdio.h>
  5. #include <unistd.h>
  6. #include <malloc.h>
  7. #include <string.h>
  8. #include "pnmread.h"
  9.  
  10. extern int optind;
  11. extern char *optarg;
  12.  
  13. /* This mask defines the order how the pixels will be copied into the output
  14.    buffer */
  15. static char bit_value[8] = {
  16.   128,
  17.   64,
  18.   32,
  19.   16,
  20.   8,
  21.   4,
  22.   2,
  23.   1
  24. };
  25.  
  26. typedef struct {
  27.   int x_dpi;
  28.   int y_dpi;
  29.   int pins;
  30.   int dbl;
  31.   int real360;
  32.   int bytes;
  33.   int maxwidth;
  34.   int formfeed;
  35.   int linefeed;
  36.   int htabs;
  37.   int interlace;
  38.   int printeven;
  39.   int printodd;
  40.   int reset;
  41.   int y_margin;
  42.   int x_margin;
  43.   int init;
  44.   char odd_blue[3];
  45.   char even_blue[3];
  46.   char odd_yellow[3];
  47.   char even_yellow[3];
  48.   char odd_red[3];
  49.   char even_red[3];
  50.   char odd_black[3];
  51.   char even_black[3];
  52. } NecP6_Opts;
  53.  
  54. #ifdef __STDC__
  55. static void necp6_decode_args(int argc, char *argv[], NecP6_Opts *necp6_opts)
  56. #else
  57. static void necp6_decode_args(argc, argv, necp6_opts)
  58. int argc;
  59. char *argv[];
  60. NecP6_Opts *necp6_opts;
  61. #endif
  62.  
  63. {
  64.   int opt;
  65.   int tmp;
  66.   int xtmp[3];
  67.  
  68.   /* print out options */
  69.   if(!argc) {
  70.     fprintf(stderr, "    -o 360x360dpi [default] (Max. width: 4896)\n");
  71.     fprintf(stderr, "    -o 180x180dpi           (Max. width: 2446)\n");
  72.     fprintf(stderr, "    -o real360x360dpi       (Max. width: 4896)\n");
  73.     fprintf(stderr, "    -o formfeed -o linefeed -o noreset -o noinit\n");
  74.     fprintf(stderr, "    -o x_margin=[-]pixel  -o y_margin=[-]pixel\n");
  75.     fprintf(stderr, "    -o htabs=int (1/180'')\n");
  76.     fprintf(stderr, "    [-o interlace_360 | -o interlace_180]\n");
  77.     fprintf(stderr, "    [-o print_odd | -o print_even]\n");
  78.     fprintf(stderr, "    -o odd=hex  (default: 333)\n");
  79.     fprintf(stderr, "    -o even=hex (default: ccc)\n");
  80.  
  81.     if(strcmp(argv[0], "necp6_mono")) {
  82.       fprintf(stderr, "    -o odd_cyan=(hex)    -o even_cyan=(hex)\n");
  83.       fprintf(stderr, "    -o odd_magenta=(hex) -o even_magenta=(hex)\n");
  84.       fprintf(stderr, "    -o odd_yellow=(hex)  -o odd_yellow=(hex)\n");
  85.       fprintf(stderr, "    -o even_black=(hex)  -o even_black=(hex)\n");
  86.     }
  87.  
  88.     return;
  89.   }
  90.  
  91.   /* default values for options */
  92.   necp6_opts->x_dpi          = 360;
  93.   necp6_opts->y_dpi          = 360;
  94.   necp6_opts->x_margin       = 0;
  95.   necp6_opts->y_margin       = 0;
  96.   necp6_opts->pins           = 24;
  97.   necp6_opts->dbl            = 1;
  98.   necp6_opts->real360        = 0;
  99.   necp6_opts->bytes          = 3;
  100.   necp6_opts->maxwidth       = 4896;
  101.   necp6_opts->formfeed       = 0;
  102.   necp6_opts->linefeed       = 0;
  103.   necp6_opts->interlace      = 0;
  104.   necp6_opts->htabs          = 0;
  105.   necp6_opts->reset          = 1;
  106.   necp6_opts->init           = 1;
  107.   necp6_opts->printodd       = 1;
  108.   necp6_opts->printeven      = 1;
  109.   necp6_opts->odd_blue[0]    = 0x3;
  110.   necp6_opts->even_blue[0]   = 0xC;
  111.   necp6_opts->odd_red[0]     = 0x3;
  112.   necp6_opts->even_red[0]    = 0xC;
  113.   necp6_opts->odd_yellow[0]  = 0x3;
  114.   necp6_opts->even_yellow[0] = 0xC;
  115.   necp6_opts->odd_black[0]   = 0x3;
  116.   necp6_opts->even_black[0]  = 0xC;
  117.   necp6_opts->odd_blue[1]    = 0x3;
  118.   necp6_opts->even_blue[1]   = 0xC;
  119.   necp6_opts->odd_red[1]     = 0x3;
  120.   necp6_opts->even_red[1]    = 0xC;
  121.   necp6_opts->odd_yellow[1]  = 0x3;
  122.   necp6_opts->even_yellow[1] = 0xC;
  123.   necp6_opts->odd_black[1]   = 0x3;
  124.   necp6_opts->even_black[1]  = 0xC;
  125.   necp6_opts->odd_blue[2]    = 0x3;
  126.   necp6_opts->even_blue[2]   = 0xC;
  127.   necp6_opts->odd_red[2]     = 0x3;
  128.   necp6_opts->even_red[2]    = 0xC;
  129.   necp6_opts->odd_yellow[2]  = 0x3;
  130.   necp6_opts->even_yellow[2] = 0xC;
  131.   necp6_opts->odd_black[2]   = 0x3;
  132.   necp6_opts->even_black[2]  = 0xC;
  133.  
  134.   optind = 0;
  135.  
  136.   /* reading arguments */
  137.   while((opt = getopt(argc, argv, "d:o:")) != -1)
  138.     switch(opt) {
  139.     case 'o':
  140.       if(!strcmp(optarg, "360x360dpi")) {
  141.     necp6_opts->x_dpi    = 360;
  142.     necp6_opts->y_dpi    = 360;
  143.     necp6_opts->y_dpi    = 24;
  144.     necp6_opts->dbl      = 1;
  145.     necp6_opts->maxwidth = 4896;
  146.       } else
  147.  
  148.       if(!strcmp(optarg, "180x180dpi")) {
  149.     necp6_opts->x_dpi    = 180;
  150.     necp6_opts->y_dpi    = 180;
  151.     necp6_opts->pins     = 24;
  152.     necp6_opts->dbl      = 0;
  153.     necp6_opts->maxwidth = 2448;
  154.       } else
  155.  
  156.       if(!strcmp(optarg, "real360x360dpi")) {
  157.     necp6_opts->x_dpi    = 360;
  158.     necp6_opts->y_dpi    = 360;
  159.     necp6_opts->y_dpi    = 24;
  160.     necp6_opts->dbl      = 1;
  161.     necp6_opts->maxwidth = 4896;
  162.     necp6_opts->real360  = 1;
  163.       } else
  164.  
  165.       if(!strcmp(optarg, "formfeed")) {
  166.     necp6_opts->formfeed = 1;
  167.       } else
  168.  
  169.       if(!strcmp(optarg, "linefeed")) {
  170.     necp6_opts->linefeed = 1;
  171.       } else
  172.  
  173.       if(!strcmp(optarg, "noreset")) {
  174.     necp6_opts->reset = 0;
  175.       } else
  176.  
  177.       if(!strcmp(optarg, "noinit")) {
  178.     necp6_opts->init = 0;
  179.       } else
  180.  
  181.       if(!strcmp(optarg, "htabs")) {
  182.     necp6_opts->htabs = 10;
  183.       } else
  184.  
  185.       if(!strncmp(optarg, "htabs=", 6)) {
  186.     sscanf(optarg + 6, "%d", &necp6_opts->htabs);
  187.       } else
  188.  
  189.       if(!strncmp(optarg, "x_margin=", 9)) {
  190.     sscanf(optarg + 9, "%d", &necp6_opts->x_margin);
  191.       } else
  192.  
  193.       if(!strncmp(optarg, "y_margin=", 9)) {
  194.     sscanf(optarg + 9, "%d", &necp6_opts->y_margin);
  195.       } else
  196.  
  197.       if(!strcmp(optarg, "interlace_360")) {
  198.     necp6_opts->interlace = 1;
  199.       } else
  200.  
  201.       if(!strcmp(optarg, "interlace_180")) {
  202.     necp6_opts->interlace = 2;
  203.       } else
  204.  
  205.       if(!strcmp(optarg, "print_even")) {
  206.     necp6_opts->printeven = 1;
  207.     necp6_opts->printodd  = 0;
  208.       } else
  209.  
  210.       if(!strcmp(optarg, "print_odd")) {
  211.     necp6_opts->printodd  = 1;
  212.     necp6_opts->printeven = 0;
  213.       } else
  214.  
  215.       if(!strncmp(optarg, "odd=", 4)) {
  216.     sscanf(optarg + 4, "%1x%1x%1x", xtmp+0, xtmp+1, xtmp+2);
  217.     necp6_opts->odd_blue[0]   = xtmp[0];
  218.     necp6_opts->odd_red[0]    = xtmp[0];
  219.     necp6_opts->odd_yellow[0] = xtmp[0];
  220.     necp6_opts->odd_black[0]  = xtmp[0];
  221.     necp6_opts->odd_blue[1]   = xtmp[1];
  222.     necp6_opts->odd_red[1]    = xtmp[1];
  223.     necp6_opts->odd_yellow[1] = xtmp[1];
  224.     necp6_opts->odd_black[1]  = xtmp[1];
  225.     necp6_opts->odd_blue[2]   = xtmp[2];
  226.     necp6_opts->odd_red[2]    = xtmp[2];
  227.     necp6_opts->odd_yellow[2] = xtmp[2];
  228.     necp6_opts->odd_black[2]  = xtmp[2];
  229.       } else
  230.  
  231.       if(!strncmp(optarg, "even=", 5)) {
  232.     sscanf(optarg + 5, "%1x%1x%1x", xtmp+0, xtmp+1, xtmp+2);
  233.     necp6_opts->even_blue[0]   = xtmp[0];
  234.     necp6_opts->even_red[0]    = xtmp[0];
  235.     necp6_opts->even_yellow[0] = xtmp[0];
  236.     necp6_opts->even_black[0]  = xtmp[0];
  237.     necp6_opts->even_blue[1]   = xtmp[1];
  238.     necp6_opts->even_red[1]    = xtmp[1];
  239.     necp6_opts->even_yellow[1] = xtmp[1];
  240.     necp6_opts->even_black[1]  = xtmp[1];
  241.     necp6_opts->even_blue[2]   = xtmp[2];
  242.     necp6_opts->even_red[2]    = xtmp[2];
  243.     necp6_opts->even_yellow[2] = xtmp[2];
  244.     necp6_opts->even_black[2]  = xtmp[2];
  245.       } else
  246.  
  247.       if(!strncmp(optarg, "odd_cyan=", 9)) {
  248.     sscanf(optarg + 9, "%1x%1x%1x", xtmp+0, xtmp+1, xtmp+2);
  249.     necp6_opts->odd_blue[0] = xtmp[0];
  250.     necp6_opts->odd_blue[1] = xtmp[1];
  251.     necp6_opts->odd_blue[2] = xtmp[2];
  252.       } else
  253.  
  254.       if(!strncmp(optarg, "even_cyan=", 10)) {
  255.     sscanf(optarg + 10, "%1x%1x%1x", xtmp+0, xtmp+1, xtmp+2);
  256.     necp6_opts->even_blue[0] = xtmp[0];
  257.     necp6_opts->even_blue[1] = xtmp[1];
  258.     necp6_opts->even_blue[2] = xtmp[2];
  259.       } else
  260.  
  261.       if(!strncmp(optarg, "odd_magenta=", 12)) {
  262.     sscanf(optarg + 12, "%1x%1x%1x", xtmp+0, xtmp+1, xtmp+2);
  263.     necp6_opts->odd_red[0] = xtmp[0];
  264.     necp6_opts->odd_red[1] = xtmp[1];
  265.     necp6_opts->odd_red[2] = xtmp[2];
  266.       } else
  267.  
  268.       if(!strncmp(optarg, "even_magenta=", 13)) {
  269.     sscanf(optarg + 13, "%1x%1x%1x", xtmp+0, xtmp+1, xtmp+2);
  270.     necp6_opts->even_red[0] = xtmp[0];
  271.     necp6_opts->even_red[1] = xtmp[1];
  272.     necp6_opts->even_red[2] = xtmp[2];
  273.       } else
  274.  
  275.       if(!strncmp(optarg, "odd_yellow=", 11)) {
  276.     sscanf(optarg + 11, "%1x%1x%1x", xtmp+0, xtmp+1, xtmp+2);
  277.     necp6_opts->odd_yellow[0] = xtmp[0];
  278.     necp6_opts->odd_yellow[1] = xtmp[1];
  279.     necp6_opts->odd_yellow[2] = xtmp[2];
  280.       } else
  281.  
  282.       if(!strncmp(optarg, "even_yellow=", 12)) {
  283.     sscanf(optarg + 12, "%1x%1x%1x", xtmp+0, xtmp+1, xtmp+2);
  284.     necp6_opts->even_yellow[0] = xtmp[0];
  285.     necp6_opts->even_yellow[1] = xtmp[1];
  286.     necp6_opts->even_yellow[2] = xtmp[2];
  287.       } else
  288.  
  289.       if(!strncmp(optarg, "odd_black=", 10)) {
  290.     sscanf(optarg + 10, "%1x%1x%1x", xtmp+0, xtmp+1, xtmp+2);
  291.     necp6_opts->odd_black[0] = xtmp[0];
  292.     necp6_opts->odd_black[1] = xtmp[1];
  293.     necp6_opts->odd_black[2] = xtmp[2];
  294.       } else
  295.  
  296.       if(!strncmp(optarg, "even_black=", 11)) {
  297.     sscanf(optarg + 11, "%1x%1x%1x", xtmp+0, xtmp+1, xtmp+2);
  298.     necp6_opts->even_black[0] = xtmp[0];
  299.     necp6_opts->even_black[1] = xtmp[1];
  300.     necp6_opts->even_black[2] = xtmp[2];
  301.  
  302.       } else {
  303.     fprintf(stderr, "%s: Warning: unknown option %s\n", argv[0], optarg);
  304.       }
  305.  
  306.       break;
  307.     }
  308. }
  309.  
  310. /* printer specific defines */
  311. #define YELLOW 4
  312. #define RED    1
  313. #define BLUE   2
  314. #define BLACK  0
  315.  
  316. #define NECP6_LINEFEED_FULL(fd)\
  317. fputc('\033', (fd));\
  318. fputc('J', (fd));\
  319. fputc(24, (fd))
  320.  
  321. #define NECP6_LINEFEED_HIGH(fd)\
  322. fputc('\033', (fd));\
  323. fputc('J', (fd));\
  324. fputc(23, (fd));\
  325. NECP6_LF((fd))
  326.  
  327. #define NECP6_LINEFEED_180(fd,i)\
  328. fputc('\033', (fd));\
  329. fputc('J', (fd));\
  330. fputc((i), (fd))
  331.  
  332. #define NECP6_LINEFEED_HIGH_24(fd)\
  333. fputc('\033', (fd));\
  334. fputc('J', (fd));\
  335. fputc(12, (fd))
  336.  
  337. #define NECP6_LINEFEED_HIGH_23(fd)\
  338. fputc('\033', (fd));\
  339. fputc('J', (fd));\
  340. fputc(11, (fd));\
  341. NECP6_LF((fd))
  342.  
  343. #define NECP6_LINEFEED_HIGH_22(fd)\
  344. fputc('\033', (fd));\
  345. fputc('J', (fd));\
  346. fputc(11, (fd))
  347.  
  348. #define NECP6_LINEFEED_HIGH_25(fd)\
  349. fputc('\033', (fd));\
  350. fputc('J', (fd));\
  351. fputc(12, (fd));\
  352. NECP6_LF((fd))
  353.  
  354. #define NECP6_INIT_1(fd)\
  355. fputc(033,(fd));\
  356. fputc('@',(fd))
  357.  
  358. #define NECP6_INIT_2(fd)\
  359. fputc(033,(fd));\
  360. fputc('P',(fd));\
  361. fputc(033,(fd));\
  362. fputc('l',(fd));\
  363. fputc(000,(fd));\
  364. fputc('\r',(fd));\
  365. fputc(034,(fd));\
  366. fputc(063,(fd));\
  367. fputc(001,(fd))
  368.  
  369. #define NECP6_FORMFEED(fd)\
  370. fputc(12,(fd))
  371.  
  372. #define NECP6_EXIT(fd)\
  373. fputc(033,(fd));\
  374. fputc('@',(fd))
  375.  
  376. #define NECP6_COLOR(fd, color)\
  377. fputc(033,(fd));\
  378. fputc('r',(fd));\
  379. fputc(color,(fd))
  380.  
  381. #define NECP6_HTAB(fd, cnt)\
  382. fputc(033, (fd));\
  383. fputc('\\', (fd));\
  384. fputc((cnt) & 0xff, (fd));\
  385. fputc((cnt) >> 8, (fd))
  386.  
  387. #define NECP6_PRINT_360_PREFIX(fd, cnt)\
  388. fputc(034, (fd));\
  389. fputc('Z', (fd));\
  390. fputc((cnt) & 0xff, (fd));\
  391. fputc((cnt) >> 8, (fd))
  392.  
  393. #define NECP6_PRINT_180_PREFIX(fd, cnt)\
  394. fputc(033, (fd));\
  395. fputc('*', (fd));\
  396. fputc(39, (fd));\
  397. fputc((cnt) & 0xff, (fd));\
  398. fputc((cnt) >> 8, (fd))
  399.  
  400. #define NECP6_CR(fd)\
  401. fputc(13, (fd))
  402.  
  403. #define NECP6_LF(fd)\
  404. fputc(10, (fd))
  405.  
  406. /* an temporary array */
  407. static char *necp6_null = NULL;
  408.  
  409. /* checks wether printer buffer is empty */
  410. #ifdef __STDC__
  411. static int not_empty(char *b, int len)
  412. #else
  413. static int not_empty(b, len)
  414. char *b;
  415. int len;
  416. #endif
  417. {
  418.   while(len--) {
  419.     if(b[len])
  420.       return(len + 1);
  421.   }
  422.  
  423.   return(0);
  424. }
  425.  
  426. /* prints one buffer in 360 dpi with */
  427. #ifdef __STDC__
  428. static void necp6_print_stripe(FILE *fd, char *buffer, int len,
  429.                    NecP6_Opts *opts)
  430. #else
  431. static void necp6_print_stripe(fd, buffer, len, opts)
  432. FILE *fd;
  433. char *buffer;
  434. int len;
  435. NecP6_Opts *opts;
  436. #endif
  437. {
  438.   int cnt = len / opts->bytes;
  439.   int minleer;
  440.   int minleer1;
  441.   int i = 0;
  442.   int leer = 0;
  443.   int leerbegin;
  444.   int len1;
  445.   int skip = (opts->x_dpi / 180) * opts->bytes;
  446.  
  447.   /* If htabs then optimizing */
  448.   if(opts->htabs == 0) {
  449.  
  450.     NECP6_PRINT_360_PREFIX(fd, cnt);
  451.     fwrite(buffer, 1, len, fd);
  452.  
  453.   } else {
  454.  
  455.     /* minimal amount of blank space which will be skipped with tabs */
  456.     minleer = opts->htabs * skip;
  457.  
  458.     while(i < len) {
  459.       leer = i;
  460.  
  461.       do {
  462.     /* searching next empty area */
  463.     for(leerbegin = leer; buffer[leerbegin] && leerbegin < len;
  464.         leerbegin++);
  465.  
  466.     minleer1 = leerbegin + minleer;
  467.  
  468.     /* checking the length of the empty area */
  469.     for(leer = leerbegin; !buffer[leer] && leer < len; leer++);
  470.  
  471.       /* until the empty area is large enough */
  472.       } while(leer < minleer1 && leer < len);
  473.  
  474.       /* end of the buffer ? */
  475.       if(leer == len) {
  476.     leerbegin = len;
  477.       }
  478.  
  479.       /* is there a printable area before the empty area -> print it */
  480.       if(i < leerbegin) {
  481.     len1 = leerbegin - i;
  482.  
  483.     len1 = len1 % opts->bytes
  484.       ? len1 + opts->bytes - (len1 % opts->bytes) : len1;
  485.  
  486.     leerbegin = i + len1;
  487.  
  488.     cnt = len1 / opts->bytes;
  489.  
  490.     NECP6_PRINT_360_PREFIX(fd, cnt);
  491.     fwrite(buffer + i, 1, len1, fd);
  492.       }
  493.  
  494.       /* skip the emtpy area with tab */
  495.       len1 = (leer - leerbegin) / skip;
  496.       NECP6_HTAB(fd, len1);
  497.  
  498.       i = leerbegin + len1 * skip;
  499.     }
  500.   }
  501. }
  502.  
  503. /* stores the last used color */
  504. static int necp6_last_color = 0;
  505.  
  506. /* prints one buffer with 360 dpi */
  507. #ifdef __STDC__
  508. static void necp6_print_stripe_360(FILE *fd, char *buffer, int offset, int len,
  509.                    int color, NecP6_Opts *opts)
  510. #else
  511. static void necp6_print_stripe_360(fd, buffer, offset, len, color, opts)
  512. FILE *fd;
  513. char *buffer;
  514. int offset;
  515. int len;
  516. int color;
  517. NecP6_Opts *opts;
  518. #endif
  519. {
  520.   int len1;
  521.   char *tmp_buf;
  522.   int i;
  523.   char *c;
  524.   int doublebytes;
  525.   int skip;
  526.  
  527.   if(buffer) {
  528.  
  529.     /* if there is a negative margin -> skipping the columns at the beginning */
  530.     if(opts->x_margin < 0) {
  531.       if((skip = opts->x_margin * opts->bytes * (-1)) > len)
  532.     return;
  533.       offset += skip;
  534.       len -= skip;
  535.  
  536.     /* positive margin -> tab to the right position */
  537.     } else if(opts->x_margin > 0) {
  538.       skip = opts->x_margin / 2;
  539.       NECP6_HTAB(fd, skip);
  540.  
  541.       if(skip % 2) {
  542.     NECP6_PRINT_360_PREFIX(fd, 1);
  543.     fwrite(necp6_null, 1, opts->bytes, fd);
  544.       }
  545.     }
  546.  
  547.     /* print only if buffer not empty */
  548.     if(len1 = not_empty(buffer + offset, len)) {
  549.  
  550.       /* select the right color */
  551.       if(color != necp6_last_color) {
  552.     NECP6_COLOR(fd, color);
  553.     necp6_last_color = color;
  554.       }
  555.  
  556.       len1 = len1 % opts->bytes
  557.     ? len1 + opts->bytes - (len1 % opts->bytes) : len1;
  558.  
  559.       /* real 360 dpi -> buffer will be splitted into two buffer. One buffer
  560.        * the even columns, one buffer the odd columns
  561.        */
  562.       if(opts->real360) {
  563.  
  564.     tmp_buf = malloc(len1);
  565.     c = buffer + offset;
  566.     doublebytes = opts->bytes * 2;
  567.  
  568.     /* even columns */
  569.     for(i = 0; i < len1; i++) {
  570.       if((i % doublebytes) < opts->bytes) {
  571.         tmp_buf[i] = 0;
  572.       } else {
  573.         tmp_buf[i] = c[i];
  574.       }
  575.     }
  576.  
  577.     necp6_print_stripe(fd, tmp_buf, len1, opts);
  578.  
  579.     /* odd columns */
  580.     for(i = 0; i < len1; i++) {
  581.       if((i % doublebytes) < opts->bytes) {
  582.         tmp_buf[i] = c[i];
  583.       } else {
  584.         tmp_buf[i] = 0;
  585.       }
  586.     }
  587.  
  588.     necp6_print_stripe(fd, tmp_buf, len1, opts);
  589.  
  590.     free(tmp_buf);
  591.  
  592.       } else {
  593.  
  594.     /* print without optimazion */
  595.     necp6_print_stripe(fd, buffer + offset, len1, opts);
  596.       }
  597.     }
  598.  
  599.     NECP6_CR(fd);
  600.   }
  601. }
  602.  
  603. /* prints the buffer in 180 dpi */
  604. #ifdef __STDC__
  605. static void necp6_print_stripe_180(FILE *fd, char *buffer, int len,
  606.                    int color, NecP6_Opts *opts)
  607. #else
  608. static void necp6_print_stripe_180(fd, buffer, len, color, opts)
  609. FILE *fd;
  610. char *buffer;
  611. int len;
  612. int color;
  613. NecP6_Opts *opts;
  614. #endif
  615. {
  616.   int len1;
  617.   int cnt;
  618.   int skip;
  619.  
  620.   if(buffer) {
  621.  
  622.     /* if negative margin -> skip the columns at the beginning */
  623.     if(opts->x_margin < 0) {
  624.       if((skip = opts->x_margin * opts->bytes * (-1)) > len)
  625.     return;
  626.       buffer += skip;
  627.       len -= skip;
  628.  
  629.       /* positive margin -> tab to the right position */
  630.     } else if(opts->x_margin > 0) {
  631.       NECP6_HTAB(fd, opts->x_margin);
  632.     }
  633.  
  634.     if(len1 = not_empty(buffer, len)) {
  635.       /* select the color */
  636.       if(color != necp6_last_color) {
  637.     NECP6_COLOR(fd, color);
  638.     necp6_last_color = color;
  639.       }
  640.  
  641.       len1 = len1 % opts->bytes
  642.     ? len1 + opts->bytes - (len1 % opts->bytes) : len1;
  643.  
  644.       cnt = len1 / opts->bytes;
  645.  
  646.       /* print the buffer */
  647.       NECP6_PRINT_180_PREFIX(fd, cnt);
  648.       fwrite(buffer, 1, len1, fd);
  649.     }
  650.  
  651.     NECP6_CR(fd);
  652.   }
  653. }
  654.  
  655. /* copy the upper 3 halfbytes and sets lower region to zero */
  656. #ifdef __STDC__
  657. static void bitcopy_u_u(char *dest, char *src, int len)
  658. #else
  659. static void bitcopy_u_u(dest, src, len)
  660. char *dest;
  661. char *src;
  662. int len;
  663. #endif
  664. {
  665.   int i;
  666.  
  667.   if(dest) {
  668.  
  669.     src += len;
  670.  
  671.     for(i = 0; i < len; i++) {
  672.       switch(i%3) {
  673.       case 0:
  674.     *(dest++) = *(src++);
  675.     break;
  676.       case 1:
  677.     *(dest++) = *(src++) & 0xF0;
  678.     break;
  679.       case 2:
  680.     *(dest++) = '\0';
  681.     src++;
  682.     break;
  683.       }
  684.     }
  685.   }
  686. }
  687.  
  688. /* copy the lower region to the upper region, settung lower region to zero */
  689. #ifdef __STDC__
  690. static void bitcopy_l_u(char *dest, char *src, int len)
  691. #else
  692. static void bitcopy_l_u(dest, src, len)
  693. char *dest;
  694. char *src;
  695. int len;
  696. #endif
  697. {
  698.   int i;
  699.  
  700.   if(dest) {
  701.  
  702.     src += len;
  703.  
  704.     for(i = 0, src++; i < len; i++) {
  705.       switch(i%3) {
  706.       case 0:
  707.     *dest = (*src & 0xF) << 4;
  708.     src++;
  709.     *dest |= (*src & 0xF0) >> 4;
  710.     dest++;
  711.     break;
  712.       case 1:
  713.     *(dest++) = (*(src++) & 0xF) << 4;
  714.     break;
  715.       case 2:
  716.     *(dest++) = '\0';
  717.     src++;
  718.     break;
  719.       }
  720.     }
  721.   }
  722. }
  723.  
  724. /* copy the upper region to the lower region */
  725. #ifdef __STDC__
  726. static void bitcopy_u_l(char *dest, char *src, int len)
  727. #else
  728. static void bitcopy_u_l(dest, src, len)
  729. char *dest;
  730. char *src;
  731. int len;
  732. #endif
  733. {
  734.   int i;
  735.  
  736.   if(dest) {
  737.  
  738.     src += len;
  739.  
  740.     for(i = 0, dest++; i < len; i++) {
  741.       switch(i%3) {
  742.       case 0:
  743.     *(dest++) |= (*src & 0xF0) >> 4;
  744.     *dest      = (*(src++) & 0xF) << 4;
  745.     break;
  746.       case 1:
  747.     *(dest++) |= (*(src++) & 0xF0) >> 4;
  748.     break;
  749.       case 2:
  750.     dest++;    src++;
  751.     break;
  752.       }
  753.     }
  754.   }
  755. }
  756.  
  757. /* copy upper region to upper region. setting lower region to zero
  758.  * using mask
  759.  */
  760. #ifdef __STDC__
  761. static void bitcopy_u_u_mask(char *dest, char *src, int len, char mask[3])
  762. #else
  763. static void bitcopy_u_u_mask(dest, src, len, mask)
  764. char *dest;
  765. char *src;
  766. int len;
  767. char mask[3];
  768. #endif
  769. {
  770.   int i;
  771.   char m1, m2;
  772.  
  773.   m1 = (mask[0] << 4) | mask[1];
  774.   m2 = mask[2] << 4;
  775.  
  776.   if(dest) {
  777.     for(i = 0; i < len; i++) {
  778.       switch(i%3) {
  779.       case 0:
  780.     *(dest++) = *(src++) & m1;
  781.     break;
  782.       case 1:
  783.     *(dest++) = *(src++) & 0xF0 & m2;
  784.     break;
  785.       case 2:
  786.     *(dest++) = '\0';
  787.     src++;
  788.     break;
  789.       }
  790.     }
  791.   }
  792. }
  793.  
  794. /* copy lower region to lower region using mask
  795.  */
  796. #ifdef __STDC__
  797. static void bitcopy_l_l_mask(char *dest, char *src, int len, char mask[3])
  798. #else
  799. static void bitcopy_l_l_mask(dest, src, len, mask)
  800. char *dest;
  801. char *src;
  802. int len;
  803. char mask[3];
  804. #endif
  805. {
  806.   int i;
  807.   char m1, m2;
  808.  
  809.   m1 = mask[0];
  810.   m2 = (mask[1] << 4) | mask[2];
  811.  
  812.   if(dest) {
  813.     for(i = 0; i < len; i++) {
  814.       switch(i%3) {
  815.       case 0:
  816.     dest++;
  817.     src++;
  818.     break;
  819.       case 1:
  820.     *(dest++) |= *(src++) & 0xF & m1;
  821.     break;
  822.       case 2:
  823.     *(dest++) = *(src++) & m2;
  824.     break;
  825.       }
  826.     }
  827.   }
  828. }
  829.  
  830. /* copy lower region to upper region. setting lower region to zero
  831.  * using mask
  832.  */
  833. #ifdef __STDC__
  834. static void bitcopy_l_u_mask(char *dest, char *src, int len, char mask[3])
  835. #else
  836. static void bitcopy_l_u_mask(dest, src, len, mask)
  837. char *dest;
  838. char *src;
  839. int len;
  840. char mask[3];
  841. #endif
  842. {
  843.   int i;
  844.   char m1, m2;
  845.  
  846.   m1 = mask[0];
  847.   m2 = (mask[1] << 4) | mask[2];
  848.  
  849.   if(dest) {
  850.     for(i = 0, src++; i < len; i++) {
  851.       switch(i%3) {
  852.       case 0:
  853.     *dest = (*src & 0xF & m1) << 4;
  854.     src++;
  855.     *dest |= (*src & 0xF0 & m2) >> 4;
  856.     dest++;
  857.     break;
  858.       case 1:
  859.     *(dest++) = (*(src++) & 0xF & m2) << 4;
  860.     break;
  861.       case 2:
  862.     *(dest++) = '\0';
  863.     src++;
  864.     break;
  865.       }
  866.     }
  867.   }
  868. }
  869.  
  870. /* copy upper region to lower region using mask
  871.  */
  872. #ifdef __STDC__
  873. static void bitcopy_u_l_mask(char *dest, char *src, int len, char mask[3])
  874. #else
  875. static void bitcopy_u_l_mask(dest, src, len, mask)
  876. char *dest;
  877. char *src;
  878. int len;
  879. char mask[3];
  880. #endif
  881. {
  882.   int i;
  883.   char m1, m2;
  884.  
  885.   m1 = (mask[0] << 4) | mask[1];
  886.   m2 = mask[2] << 4;
  887.  
  888.   if(dest) {
  889.     for(i = 0, dest++; i < len; i++) {
  890.       switch(i%3) {
  891.       case 0:
  892.     *(dest++) |= (*src & 0xF0 & m1) >> 4;
  893.     *dest      = (*(src++) & 0xF & m1) << 4;
  894.     break;
  895.       case 1:
  896.     *(dest++) |= (*(src++) & 0xF0 & m2) >> 4;
  897.     break;
  898.       case 2:
  899.     dest++;    src++;
  900.     break;
  901.       }
  902.     }
  903.   }
  904. }
  905.  
  906. /* stores the interlaced buffers */
  907. static char *buffer_yellow_old  = NULL;
  908. static char *buffer_red_old     = NULL;
  909. static char *buffer_blue_old    = NULL;
  910. static char *buffer_black_old   = NULL;
  911.  
  912. static char *buffer_yellow_act  = NULL;
  913. static char *buffer_red_act     = NULL;
  914. static char *buffer_blue_act    = NULL;
  915. static char *buffer_black_act   = NULL;
  916.  
  917. static int sav_len;
  918.  
  919. /* prints all buffers in 360 or 180 dpi */
  920. #ifdef __STDC__
  921. static void necp6_print_buffer(FILE *fd, char *buffer_yellow,
  922.                    char *buffer_red, char *buffer_blue,
  923.                    char *buffer_black, int len,
  924.                    NecP6_Opts *opts)
  925. #else
  926. static void necp6_print_buffer(fd, buffer_yellow, buffer_red, buffer_blue,
  927.                    buffer_black, len, opts)
  928. FILE *fd;
  929. char *buffer_yellow;
  930. char *buffer_red;
  931. char *buffer_blue;
  932. char *buffer_black;
  933. int len;
  934. NecP6_Opts *opts;
  935. #endif
  936. {
  937.   int c;
  938.   int len2;
  939. static int first = 0;
  940.  
  941.   if(len) {
  942.     if(opts->x_dpi == 360) {
  943.       switch(opts->interlace) {
  944.  
  945.       case 2: /* interlace_180 */
  946.     len2 = len * 2;
  947.  
  948.     /* First pass ? */
  949.     if(!buffer_black_old) {
  950.  
  951.       sav_len = len;
  952.  
  953.       if(buffer_yellow) {
  954.         buffer_yellow_old = malloc(len2);
  955.         buffer_red_old    = malloc(len2);
  956.         buffer_blue_old   = malloc(len2);
  957.         buffer_yellow_act = malloc(len2);
  958.         buffer_red_act    = malloc(len2);
  959.         buffer_blue_act   = malloc(len2);
  960.       }
  961.  
  962.       buffer_black_old  = malloc(len2);
  963.       buffer_black_act  = malloc(len2);
  964.  
  965.       bitcopy_u_u_mask(buffer_yellow_act, buffer_yellow, len2,
  966.                opts->odd_yellow);
  967.       bitcopy_u_u_mask(buffer_red_act,    buffer_red,    len2,
  968.                opts->odd_red);
  969.       bitcopy_u_u_mask(buffer_blue_act,   buffer_blue,   len2,
  970.                opts->odd_blue);
  971.       bitcopy_u_u_mask(buffer_black_act,  buffer_black,  len2,
  972.                opts->odd_black);
  973.  
  974.       bitcopy_l_l_mask(buffer_yellow_act, buffer_yellow, len2,
  975.                   opts->even_yellow);
  976.       bitcopy_l_l_mask(buffer_red_act,    buffer_red,    len2,
  977.                opts->even_red);
  978.       bitcopy_l_l_mask(buffer_blue_act,   buffer_blue,   len2,
  979.                opts->even_blue);
  980.       bitcopy_l_l_mask(buffer_black_act,  buffer_black,  len2,
  981.                opts->even_black);
  982.  
  983.       bitcopy_u_u_mask(buffer_yellow_old, buffer_yellow, len2,
  984.                opts->even_yellow);
  985.       bitcopy_u_u_mask(buffer_red_old,    buffer_red,    len2,
  986.                opts->even_red);
  987.       bitcopy_u_u_mask(buffer_blue_old,   buffer_blue,   len2,
  988.                opts->even_blue);
  989.       bitcopy_u_u_mask(buffer_black_old,  buffer_black,  len2,
  990.                opts->even_black);
  991.  
  992.       if(opts->printeven) {
  993.         necp6_print_stripe_360(fd,buffer_yellow_act, 0, len, YELLOW, opts);
  994.         necp6_print_stripe_360(fd,buffer_red_act,    0, len, RED,    opts);
  995.         necp6_print_stripe_360(fd,buffer_blue_act,   0, len, BLUE,   opts);
  996.         necp6_print_stripe_360(fd,buffer_black_act,  0, len, BLACK,  opts);
  997.       }
  998.  
  999.       if(opts->printodd) {
  1000.         necp6_print_stripe_360(fd,buffer_yellow_old, 0, len, YELLOW, opts);
  1001.         necp6_print_stripe_360(fd,buffer_red_old,    0, len, RED,    opts);
  1002.         necp6_print_stripe_360(fd,buffer_blue_old,   0, len, BLUE,   opts);
  1003.         necp6_print_stripe_360(fd,buffer_black_old,  0, len, BLACK,  opts);
  1004.       }
  1005.  
  1006.       NECP6_LF(fd);
  1007.  
  1008.       if(opts->printeven) {
  1009.         necp6_print_stripe_360(fd,buffer_yellow_act,len,len, YELLOW, opts);
  1010.         necp6_print_stripe_360(fd,buffer_red_act,  len, len, RED,    opts);
  1011.         necp6_print_stripe_360(fd,buffer_blue_act, len, len, BLUE,   opts);
  1012.         necp6_print_stripe_360(fd,buffer_black_act,len, len, BLACK,  opts);
  1013.       }
  1014.  
  1015.       if(opts->printodd) {
  1016.         necp6_print_stripe_360(fd,buffer_yellow_old,len,len, YELLOW, opts);
  1017.         necp6_print_stripe_360(fd,buffer_red_old,  len, len, RED,    opts);
  1018.         necp6_print_stripe_360(fd,buffer_blue_old, len, len, BLUE,   opts);
  1019.         necp6_print_stripe_360(fd,buffer_black_old,len, len, BLACK,  opts);
  1020.       }
  1021.  
  1022.       bitcopy_l_u_mask(buffer_yellow_old, buffer_yellow, len2,
  1023.                opts->odd_yellow);
  1024.       bitcopy_l_u_mask(buffer_red_old,    buffer_red,    len2,
  1025.                opts->odd_red);
  1026.       bitcopy_l_u_mask(buffer_blue_old,   buffer_blue,   len2,
  1027.                opts->odd_blue);
  1028.       bitcopy_l_u_mask(buffer_black_old,  buffer_black,  len2,
  1029.                opts->odd_black);
  1030.  
  1031.       NECP6_LINEFEED_HIGH_23(fd);
  1032.  
  1033.     } else { /* Not the first pass */
  1034.  
  1035.       bitcopy_u_l_mask(buffer_yellow_old, buffer_yellow, len2,
  1036.                opts->even_yellow);
  1037.       bitcopy_u_l_mask(buffer_red_old,    buffer_red,    len2,
  1038.                opts->even_red);
  1039.       bitcopy_u_l_mask(buffer_blue_old,   buffer_blue,   len2,
  1040.                opts->even_blue);
  1041.       bitcopy_u_l_mask(buffer_black_old,  buffer_black,  len2,
  1042.                opts->even_black);
  1043.  
  1044.       if(opts->printodd) {
  1045.         necp6_print_stripe_360(fd,buffer_yellow_old, 0, len, YELLOW, opts);
  1046.         necp6_print_stripe_360(fd,buffer_red_old,    0, len, RED,    opts);
  1047.         necp6_print_stripe_360(fd,buffer_blue_old,   0, len, BLUE,   opts);
  1048.         necp6_print_stripe_360(fd,buffer_black_old,  0, len, BLACK,  opts);
  1049.       }
  1050.  
  1051.       NECP6_LF(fd);
  1052.  
  1053.       if(opts->printodd) {
  1054.         necp6_print_stripe_360(fd,buffer_yellow_old,len,len, YELLOW, opts);
  1055.         necp6_print_stripe_360(fd,buffer_red_old,  len, len, RED,    opts);
  1056.         necp6_print_stripe_360(fd,buffer_blue_old, len, len, BLUE,   opts);
  1057.         necp6_print_stripe_360(fd,buffer_black_old,len, len, BLACK,  opts);
  1058.       }
  1059.  
  1060.       NECP6_LINEFEED_HIGH_23(fd);
  1061.  
  1062.       bitcopy_u_u_mask(buffer_yellow_act, buffer_yellow, len2,
  1063.                opts->odd_yellow);
  1064.       bitcopy_u_u_mask(buffer_red_act,    buffer_red,    len2,
  1065.                opts->odd_red);
  1066.       bitcopy_u_u_mask(buffer_blue_act,   buffer_blue,   len2,
  1067.                opts->odd_blue);
  1068.       bitcopy_u_u_mask(buffer_black_act,  buffer_black,  len2,
  1069.                opts->odd_black);
  1070.       bitcopy_l_l_mask(buffer_yellow_act, buffer_yellow, len2,
  1071.                opts->even_yellow);
  1072.       bitcopy_l_l_mask(buffer_red_act,    buffer_red,    len2,
  1073.                opts->even_red);
  1074.       bitcopy_l_l_mask(buffer_blue_act,   buffer_blue,   len2,
  1075.                opts->even_blue);
  1076.       bitcopy_l_l_mask(buffer_black_act,  buffer_black,  len2,
  1077.                opts->even_black);
  1078.  
  1079.       if(opts->printeven) {
  1080.         necp6_print_stripe_360(fd,buffer_yellow_act, 0, len, YELLOW, opts);
  1081.         necp6_print_stripe_360(fd,buffer_red_act,    0, len, RED,    opts);
  1082.         necp6_print_stripe_360(fd,buffer_blue_act,   0, len, BLUE,   opts);
  1083.         necp6_print_stripe_360(fd,buffer_black_act,  0, len, BLACK,  opts);
  1084.       }
  1085.  
  1086.       NECP6_LF(fd);
  1087.  
  1088.       if(opts->printeven) {
  1089.         necp6_print_stripe_360(fd,buffer_yellow_act,len,len, YELLOW, opts);
  1090.         necp6_print_stripe_360(fd,buffer_red_act,   len,len, RED,    opts);
  1091.         necp6_print_stripe_360(fd,buffer_blue_act,  len,len, BLUE,   opts);
  1092.         necp6_print_stripe_360(fd,buffer_black_act, len,len, BLACK,  opts);
  1093.       }
  1094.  
  1095.       NECP6_LINEFEED_HIGH_23(fd);
  1096.  
  1097.       bitcopy_l_u_mask(buffer_yellow_old, buffer_yellow, len2,
  1098.                opts->odd_yellow);
  1099.       bitcopy_l_u_mask(buffer_red_old,    buffer_red,    len2,
  1100.                opts->odd_red);
  1101.       bitcopy_l_u_mask(buffer_blue_old,   buffer_blue,   len2,
  1102.                opts->odd_blue);
  1103.       bitcopy_l_u_mask(buffer_black_old,  buffer_black,  len2,
  1104.                opts->odd_black);
  1105.     }
  1106.     break;
  1107.  
  1108.       case 1: /* interlace_360 */
  1109.  
  1110.     /* FIrst pass ? */
  1111.     if(!buffer_black_old) {
  1112.       if(opts->printodd) {
  1113.         necp6_print_stripe_360(fd, buffer_yellow, 0, len, YELLOW, opts);
  1114.         necp6_print_stripe_360(fd, buffer_red,    0, len, RED,    opts);
  1115.         necp6_print_stripe_360(fd, buffer_blue,   0, len, BLUE,   opts);
  1116.         necp6_print_stripe_360(fd, buffer_black,  0, len, BLACK,  opts);
  1117.       }
  1118.  
  1119.       NECP6_LF(fd);
  1120.  
  1121.       if(buffer_yellow) {
  1122.         buffer_yellow_old = malloc(len);
  1123.         buffer_red_old    = malloc(len);
  1124.         buffer_blue_old   = malloc(len);
  1125.       }
  1126.       buffer_black_old  = malloc(len);
  1127.  
  1128.       sav_len = len;
  1129.  
  1130.       bitcopy_u_u(buffer_yellow_old, buffer_yellow, len);
  1131.       bitcopy_u_u(buffer_red_old,    buffer_red,    len);
  1132.       bitcopy_u_u(buffer_blue_old,   buffer_blue,   len);
  1133.       bitcopy_u_u(buffer_black_old,  buffer_black,  len);
  1134.  
  1135.       if(opts->printeven) {
  1136.         necp6_print_stripe_360(fd,buffer_yellow_old, 0, len, YELLOW, opts);
  1137.         necp6_print_stripe_360(fd,buffer_red_old,    0, len, RED,    opts);
  1138.         necp6_print_stripe_360(fd,buffer_blue_old,   0, len, BLUE,   opts);
  1139.         necp6_print_stripe_360(fd,buffer_black_old,  0, len, BLACK,  opts);
  1140.       }
  1141.  
  1142.       bitcopy_l_u(buffer_yellow_old, buffer_yellow, len);
  1143.       bitcopy_l_u(buffer_red_old,    buffer_red,    len);
  1144.       bitcopy_l_u(buffer_blue_old,   buffer_blue,   len);
  1145.       bitcopy_l_u(buffer_black_old,  buffer_black,  len);
  1146.  
  1147.       NECP6_LINEFEED_HIGH_24(fd);
  1148.  
  1149.     } else { /* not the first pass */
  1150.  
  1151.       bitcopy_u_l(buffer_yellow_old, buffer_yellow, len);
  1152.       bitcopy_u_l(buffer_red_old,    buffer_red,    len);
  1153.       bitcopy_u_l(buffer_blue_old,   buffer_blue,   len);
  1154.       bitcopy_u_l(buffer_black_old,  buffer_black,  len);
  1155.  
  1156.       if(opts->printeven) {
  1157.         necp6_print_stripe_360(fd,buffer_yellow_old, 0, len, YELLOW, opts);
  1158.         necp6_print_stripe_360(fd,buffer_red_old,    0, len, RED,    opts);
  1159.         necp6_print_stripe_360(fd,buffer_blue_old,   0, len, BLUE,   opts);
  1160.         necp6_print_stripe_360(fd,buffer_black_old,  0, len, BLACK,  opts);
  1161.       }
  1162.  
  1163.       NECP6_LINEFEED_HIGH_23(fd);
  1164.  
  1165.       bitcopy_l_u(buffer_yellow_old, buffer_yellow, len);
  1166.       bitcopy_l_u(buffer_red_old,    buffer_red,    len);
  1167.       bitcopy_l_u(buffer_blue_old,   buffer_blue,   len);
  1168.       bitcopy_l_u(buffer_black_old,  buffer_black,  len);
  1169.  
  1170.       if(opts->printodd) {
  1171.         necp6_print_stripe_360(fd, buffer_yellow, 0, len, YELLOW, opts);
  1172.         necp6_print_stripe_360(fd, buffer_red,    0, len, RED,    opts);
  1173.         necp6_print_stripe_360(fd, buffer_blue,   0, len, BLUE,   opts);
  1174.         necp6_print_stripe_360(fd, buffer_black,  0, len, BLACK,  opts);
  1175.       }
  1176.  
  1177.       NECP6_LINEFEED_HIGH_25(fd);
  1178.     }
  1179.     break;
  1180.  
  1181.       default: /* No interlacing */
  1182.  
  1183.     if(first == 1) {
  1184.       first = 2;
  1185.     } else {
  1186.       NECP6_LINEFEED_HIGH(fd);
  1187.     }
  1188.  
  1189.     necp6_print_stripe_360(fd, buffer_yellow, 0, len, YELLOW, opts);
  1190.     necp6_print_stripe_360(fd, buffer_red,    0, len, RED,    opts);
  1191.     necp6_print_stripe_360(fd, buffer_blue,   0, len, BLUE,   opts);
  1192.     necp6_print_stripe_360(fd, buffer_black,  0, len, BLACK,  opts);
  1193.  
  1194.     NECP6_LF(fd);
  1195.  
  1196.     necp6_print_stripe_360(fd, buffer_yellow, len, len, YELLOW, opts);
  1197.     necp6_print_stripe_360(fd, buffer_red,    len, len, RED,    opts);
  1198.     necp6_print_stripe_360(fd, buffer_blue,   len, len, BLUE,   opts);
  1199.     necp6_print_stripe_360(fd, buffer_black,  len, len, BLACK,  opts);
  1200.  
  1201.     break;
  1202.       }
  1203.     } else { /* 180 dpi */
  1204.  
  1205.       if(first == 1) {
  1206.     first = 2;
  1207.       } else {
  1208.     NECP6_LINEFEED_FULL(fd);
  1209.       }
  1210.  
  1211.       necp6_print_stripe_180(fd, buffer_yellow, len, YELLOW, opts);
  1212.       necp6_print_stripe_180(fd, buffer_red   , len, RED,    opts);
  1213.       necp6_print_stripe_180(fd, buffer_blue  , len, BLUE,   opts);
  1214.       necp6_print_stripe_180(fd, buffer_black , len, BLACK,  opts);
  1215.     }
  1216.   } else { /* before the first pass or after tha last pass */
  1217.  
  1218.     if(necp6_null) { /* after the last pass */
  1219.       switch(opts->interlace) {
  1220.       case 1: /* interlace_360 */
  1221.     if(opts->printeven) {
  1222.       necp6_print_stripe_360(fd,buffer_yellow_old,0,sav_len, YELLOW, opts);
  1223.       necp6_print_stripe_360(fd,buffer_red_old,   0,sav_len, RED,    opts);
  1224.       necp6_print_stripe_360(fd,buffer_blue_old,  0,sav_len, BLUE,   opts);
  1225.       necp6_print_stripe_360(fd,buffer_black_old, 0,sav_len, BLACK,  opts);
  1226.     }
  1227.  
  1228.     if(buffer_yellow_old) {
  1229.       free(buffer_yellow_old);
  1230.       free(buffer_red_old);
  1231.       free(buffer_blue_old);
  1232.     }
  1233.  
  1234.     free(buffer_black_old);
  1235.  
  1236.     buffer_yellow_old = NULL;
  1237.     buffer_red_old    = NULL;
  1238.     buffer_blue_old   = NULL;
  1239.     buffer_black_old  = NULL;
  1240.     break;
  1241.  
  1242.       case 2: /* interlace_180 */
  1243.     if(opts->printodd) {
  1244.       necp6_print_stripe_360(fd,buffer_yellow_old,0,sav_len, YELLOW, opts);
  1245.       necp6_print_stripe_360(fd,buffer_red_old,   0,sav_len, RED,    opts);
  1246.       necp6_print_stripe_360(fd,buffer_blue_old,  0,sav_len, BLUE,   opts);
  1247.       necp6_print_stripe_360(fd,buffer_black_old, 0,sav_len, BLACK,  opts);
  1248.     }
  1249.  
  1250.     NECP6_LF(fd);
  1251.  
  1252.     if(opts->printodd) {
  1253.       necp6_print_stripe_360(fd,buffer_yellow_old,len,sav_len,YELLOW,opts);
  1254.       necp6_print_stripe_360(fd,buffer_red_old,   len,sav_len,RED,   opts);
  1255.       necp6_print_stripe_360(fd,buffer_blue_old,  len,sav_len,BLUE,  opts);
  1256.       necp6_print_stripe_360(fd,buffer_black_old, len,sav_len,BLACK, opts);
  1257.     }
  1258.  
  1259.     if(buffer_yellow_old) {
  1260.       free(buffer_yellow_old);
  1261.       free(buffer_red_old);
  1262.       free(buffer_blue_old);
  1263.       free(buffer_yellow_act);
  1264.       free(buffer_red_act);
  1265.       free(buffer_blue_act);
  1266.     }
  1267.  
  1268.     free(buffer_black_old);
  1269.     free(buffer_black_act);
  1270.  
  1271.     buffer_yellow_old = NULL;
  1272.     buffer_red_old    = NULL;
  1273.     buffer_blue_old   = NULL;
  1274.     buffer_black_old  = NULL;
  1275.     buffer_yellow_act = NULL;
  1276.     buffer_red_act    = NULL;
  1277.     buffer_blue_act   = NULL;
  1278.     buffer_black_act  = NULL;
  1279.  
  1280.     break;
  1281.       }
  1282.  
  1283.       free(necp6_null);
  1284.       necp6_null = NULL;
  1285.  
  1286.     } else { /* before first pass */
  1287.       necp6_null = malloc(opts->bytes);
  1288.       memset(necp6_null, 0, opts->bytes);
  1289.       first = 1;
  1290.     }
  1291.   }
  1292. }
  1293.  
  1294. /* prints monochrome graphics */
  1295. #ifdef __STDC__
  1296. int necp6_mono(FILE *in, FILE *out, int argc, char *argv[])
  1297. #else
  1298. int necp6_mono(in, out, argc, argv)
  1299. FILE *in;
  1300. FILE *out;
  1301. int argc;
  1302. char *argv[];
  1303. #endif
  1304. {
  1305.   NecP6_Opts necp6_opts;
  1306.   Pnm_Info *pnm_info;
  1307.   char *out_buffer;
  1308.   long line, col;
  1309.   int pixel;
  1310.   int outlen;
  1311.   int byte;
  1312.   int out_index;
  1313.   int linlen;
  1314.   int dblplusone;
  1315.   int value;
  1316.   char *outp;
  1317.   int tmp1;
  1318.   int eightpdbl;
  1319.   int i;
  1320.  
  1321.   /* printing usage */
  1322.   if(!in) {
  1323.     fprintf(stderr, "\n  Options for driver '%s'\n", argv[0]);
  1324.     necp6_decode_args(0, argv, NULL);
  1325.     return(1);
  1326.   }
  1327.  
  1328.   /* reading header from pnm file */
  1329.   if(!(pnm_info = pnm_get_info(in))) {
  1330.     fprintf(stderr, "%s: Can't decode PNM file\n", argv[0]);
  1331.     return(1);
  1332.   }
  1333.  
  1334.   switch(pnm_info->type) {
  1335.   case PGM:
  1336.     fprintf(stderr, "%s: Greyscales ignored\n", argv[0]);
  1337.     break;
  1338.  
  1339.   case PPM:
  1340.     fprintf(stderr, "%s: Colors ignored\n", argv[0]);
  1341.     break;
  1342.  
  1343.   case PBM:
  1344.     break;
  1345.  
  1346.   default:
  1347.     fprintf(stderr, "%s: Unknown PNM type\n", argv[0]);
  1348.     return(1);
  1349.     break;
  1350.   }
  1351.  
  1352.   /* decoding driver specific args */
  1353.   necp6_decode_args(argc, argv, &necp6_opts);
  1354.  
  1355.   if(necp6_opts.y_margin > pnm_info->height)
  1356.     return(0);
  1357.  
  1358.   if(pnm_info->width + necp6_opts.x_margin > necp6_opts.maxwidth) {
  1359.     fprintf(stderr, "%s:  picture with %d larger than %d (Margin: %d)\n",
  1360.         argv[0], pnm_info->width, necp6_opts.maxwidth, necp6_opts.x_margin);
  1361.     return(1);
  1362.   }
  1363.  
  1364.   /* some useful constants */
  1365.   dblplusone = necp6_opts.dbl + 1;
  1366.   eightpdbl  = dblplusone * 8;
  1367.  
  1368.   linlen     = necp6_opts.bytes * pnm_info->width;
  1369.   outlen     = linlen * (necp6_opts.dbl + 1);
  1370.  
  1371.   /* allocating output buffer */
  1372.   if(!(out_buffer = malloc(outlen))) {
  1373.     fprintf(stderr, "%s: malloc error\n", argv[0]);
  1374.     return(1);
  1375.   }
  1376.  
  1377.   /* init printer */
  1378.   if(necp6_opts.init) {
  1379.     NECP6_INIT_1(out);
  1380.   }
  1381.  
  1382.   NECP6_INIT_2(out);
  1383.  
  1384.   /* if margin negative -> skipping the lines at the beginning */
  1385.   if(necp6_opts.y_margin < 0) {
  1386.     for(line = necp6_opts.y_margin; line < 0; line++) {
  1387.       for(col = 0; col < pnm_info->width; col++) {
  1388.     (*pnm_info->get_pixel_mono)(&pixel, in);
  1389.       }
  1390.       (*pnm_info->get_pixel_mono)(NULL, in);
  1391.     }
  1392.     pnm_info->height += necp6_opts.y_margin;
  1393.  
  1394.   /* positive margin -> tab to the right position */
  1395.   } else if(necp6_opts.y_margin > 0) {
  1396.     if(necp6_opts.x_dpi == 360) {
  1397.       line = necp6_opts.y_margin / 2;
  1398.       if(necp6_opts.y_margin % 2) {
  1399.     NECP6_LF(out);
  1400.       }
  1401.       tmp1 = line / 127;
  1402.       for(i = 0; i < tmp1; i++) {
  1403.     NECP6_LINEFEED_180(out,127);
  1404.       }
  1405.       if(line % 127) {
  1406.     NECP6_LINEFEED_180(out,line % 127);
  1407.       }
  1408.     } else {
  1409.       tmp1 = necp6_opts.y_margin / 127;
  1410.       for(i = 0; i < tmp1; i++) {
  1411.     NECP6_LINEFEED_180(out,127);
  1412.       }
  1413.       if(necp6_opts.y_margin % 127) {
  1414.     NECP6_LINEFEED_180(out,necp6_opts.y_margin % 127);
  1415.       }
  1416.     }
  1417.   }
  1418.  
  1419.   /* initialization */
  1420.   necp6_print_buffer(out, NULL, NULL, NULL, NULL, 0, &necp6_opts);
  1421.  
  1422.   /* processing line by line */
  1423.   for(line = 0; line < pnm_info->height; line++) {
  1424.  
  1425.     /* if buffer full -> printing line */
  1426.     if((tmp1 = line % (necp6_opts.pins * dblplusone)) == 0) {
  1427.  
  1428.       if(line) {
  1429.     necp6_print_buffer(out, NULL, NULL, NULL, out_buffer, linlen,
  1430.                &necp6_opts);
  1431.     }
  1432.  
  1433.       /* clearing output buffer */
  1434.       memset(out_buffer, 0, outlen);
  1435.     }
  1436.  
  1437.     /* some useful constants */
  1438.     value = bit_value[(tmp1 / dblplusone) % 8];
  1439.     outp  = out_buffer + (tmp1 / eightpdbl);
  1440.  
  1441.     /* 360 dpi will be printed interlaced. The interlaced line is after the
  1442.      * first line
  1443.      */
  1444.     if(necp6_opts.dbl && (line % 2) == 1)
  1445.       outp += linlen;
  1446.  
  1447.     /* processing all pixels of one scan line */
  1448.     for(col = 0; col < pnm_info->width; col++, outp += necp6_opts.bytes) {
  1449.  
  1450.       /* reading pixel value */
  1451.       if((*pnm_info->get_pixel_mono)(&pixel, in)) {
  1452.     fprintf(stderr, "%s: Can't read pixels from PNM file\n", argv[0]);
  1453.     free(out_buffer);
  1454.     NECP6_EXIT(out);
  1455.     return(1);
  1456.       }
  1457.  
  1458.       /* setting pixel in output buffer */
  1459.       if(pixel)
  1460.     *outp |= value;
  1461.     }
  1462.  
  1463.     /* end of scan line */
  1464.     (*pnm_info->get_pixel_mono)(NULL, in);
  1465.   }
  1466.  
  1467.   /* print last buffer */
  1468.   necp6_print_buffer(out, NULL, NULL, NULL, out_buffer, linlen, &necp6_opts);
  1469.  
  1470.   necp6_print_buffer(out, NULL, NULL, NULL, NULL, 0, &necp6_opts);
  1471.  
  1472.   if(necp6_opts.dbl == 0) {
  1473.     tmp1 *= 2;
  1474.   }
  1475.  
  1476.   switch(necp6_opts.interlace) {
  1477.   case 1:
  1478.     tmp1 -= 24;
  1479.     break;
  1480.   case 2:
  1481.     tmp1 -= 25;
  1482.     break;
  1483.   }
  1484.  
  1485.   if(tmp1 < 0) {
  1486.     tmp1 = 0;
  1487.   }
  1488.  
  1489.   /* Move paper to end of the picture */
  1490.   while(tmp1--) {
  1491.     NECP6_LF(out);
  1492.   }
  1493.  
  1494.   if(necp6_opts.linefeed) {
  1495.     NECP6_LINEFEED_FULL(out);
  1496.   }
  1497.  
  1498.   if(necp6_opts.formfeed) {
  1499.     NECP6_FORMFEED(out);
  1500.   }
  1501.  
  1502.   /* reset printer */
  1503.   if(necp6_opts.reset) {
  1504.     NECP6_EXIT(out);
  1505.   }
  1506.  
  1507.   /* freeing memory */
  1508.   free(out_buffer);
  1509.  
  1510.   return(0);
  1511. }
  1512.  
  1513. /* printing color graphic */
  1514. #ifdef __STDC__
  1515. int necp6_color(FILE *in, FILE *out, int argc, char *argv[])
  1516. #else
  1517. int necp6_color(in, out, argc, argv)
  1518. FILE *in;
  1519. FILE *out;
  1520. int argc;
  1521. char *argv[];
  1522. #endif
  1523. {
  1524.   NecP6_Opts necp6_opts;
  1525.   Pnm_Info *pnm_info;
  1526.   char *out_buffer_red, *out_buffer_yellow, *out_buffer_blue,
  1527.        *out_buffer_black;
  1528.   long line, col;
  1529.   int pixel_yellow, pixel_red, pixel_blue, pixel_black;
  1530.   int outlen;
  1531.   int byte;
  1532.   int out_index;
  1533.   int linlen;
  1534.   int dblplusone;
  1535.   int value;
  1536.   char *outp_red, *outp_yellow, *outp_blue, *outp_black;
  1537.   int tmp1;
  1538.   int eightpdbl;
  1539.   int i;
  1540.  
  1541.   /* printing usage */
  1542.   if(!in) {
  1543.     fprintf(stderr, "\n  Options for driver '%s'\n", argv[0]);
  1544.     necp6_decode_args(0, argv, NULL);
  1545.     return(1);
  1546.   }
  1547.  
  1548.   /* reading header from pnm file */
  1549.   if(!(pnm_info = pnm_get_info(in))) {
  1550.     fprintf(stderr, "%s: Can't decode PNM file\n", argv[0]);
  1551.     return(1);
  1552.   }
  1553.  
  1554.   /* decoding driver specific args */
  1555.   necp6_decode_args(argc, argv, &necp6_opts);
  1556.  
  1557.   if(necp6_opts.y_margin > pnm_info->height)
  1558.     return(0);
  1559.  
  1560.   if(pnm_info->width + necp6_opts.x_margin > necp6_opts.maxwidth) {
  1561.     fprintf(stderr, "%s: picture with %d larger than %d (Margin: %d)\n",
  1562.         argv[0], pnm_info->width, necp6_opts.maxwidth, necp6_opts.x_margin);
  1563.     return(1);
  1564.   }
  1565.  
  1566.   /* some useful constants */
  1567.   dblplusone = necp6_opts.dbl + 1;
  1568.   eightpdbl  = dblplusone * 8;
  1569.  
  1570.   linlen     = necp6_opts.bytes * pnm_info->width;
  1571.   outlen     = linlen * (necp6_opts.dbl + 1);
  1572.  
  1573.   /* allocating output buffer */
  1574.   if(!(out_buffer_red = malloc(outlen))) {
  1575.     fprintf(stderr, "%s: malloc error\n", argv[0]);
  1576.     return(1);
  1577.   }
  1578.   if(!(out_buffer_yellow = malloc(outlen))) {
  1579.     fprintf(stderr, "%s: malloc error\n", argv[0]);
  1580.     free(out_buffer_red);
  1581.     return(1);
  1582.   }
  1583.   if(!(out_buffer_blue = malloc(outlen))) {
  1584.     fprintf(stderr, "%s: malloc error\n", argv[0]);
  1585.     free(out_buffer_red);
  1586.     free(out_buffer_yellow);
  1587.     return(1);
  1588.   }
  1589.   if(!(out_buffer_black = malloc(outlen))) {
  1590.     fprintf(stderr, "%s: malloc error\n", argv[0]);
  1591.     free(out_buffer_red);
  1592.     free(out_buffer_yellow);
  1593.     free(out_buffer_black);
  1594.     return(1);
  1595.   }
  1596.  
  1597.   /* init printer */
  1598.   if(necp6_opts.init) {
  1599.     NECP6_INIT_1(out);
  1600.   }
  1601.  
  1602.   NECP6_INIT_2(out);
  1603.  
  1604.   /* negative margin -> skipping lines at the beginning */
  1605.   if(necp6_opts.y_margin < 0) {
  1606.     for(line = necp6_opts.y_margin; line < 0; line++) {
  1607.       for(col = 0; col < pnm_info->width; col++) {
  1608.     (*pnm_info->get_pixel_color)(&pixel_yellow, &pixel_red,
  1609.                      &pixel_blue, &pixel_black, in);
  1610.       }
  1611.       (*pnm_info->get_pixel_color)(NULL, NULL, NULL, NULL, in);
  1612.     }
  1613.     pnm_info->height += necp6_opts.y_margin;
  1614.  
  1615.   /* positive margin -> tab to the right position */
  1616.   } else if(necp6_opts.y_margin > 0) {
  1617.     if(necp6_opts.x_dpi == 360) {
  1618.       line = necp6_opts.y_margin / 2;
  1619.       if(necp6_opts.y_margin % 2) {
  1620.     NECP6_LF(out);
  1621.       }
  1622.       tmp1 = line / 127;
  1623.       for(i = 0; i < tmp1; i++) {
  1624.     NECP6_LINEFEED_180(out,127);
  1625.       }
  1626.       if(line % 127) {
  1627.     NECP6_LINEFEED_180(out,line % 127);
  1628.       }
  1629.     } else {
  1630.       tmp1 = necp6_opts.y_margin / 127;
  1631.       for(i = 0; i < tmp1; i++) {
  1632.     NECP6_LINEFEED_180(out,127);
  1633.       }
  1634.       if(necp6_opts.y_margin % 127) {
  1635.     NECP6_LINEFEED_180(out,necp6_opts.y_margin % 127);
  1636.       }
  1637.     }
  1638.   }
  1639.  
  1640.   /* initialization */
  1641.   necp6_print_buffer(out, NULL, NULL, NULL, NULL, 0, &necp6_opts);
  1642.  
  1643.   /* processing line by line */
  1644.   for(line = 0; line < pnm_info->height; line++) {
  1645.  
  1646.     /* if buffer full -> printing line */
  1647.     if((tmp1 = line % (necp6_opts.pins * dblplusone)) == 0) {
  1648.  
  1649.       if(line) {
  1650.     necp6_print_buffer(out, out_buffer_yellow, out_buffer_red,
  1651.                out_buffer_blue, out_buffer_black, linlen,
  1652.                &necp6_opts);
  1653.     }
  1654.  
  1655.       /* clearing output buffer */
  1656.       memset(out_buffer_yellow, 0, outlen);
  1657.       memset(out_buffer_red,    0, outlen);
  1658.       memset(out_buffer_blue,   0, outlen);
  1659.       memset(out_buffer_black,  0, outlen);
  1660.     }
  1661.  
  1662.     /* some useful constants */
  1663.     value = bit_value[(tmp1 / dblplusone) % 8];
  1664.     outp_yellow  = out_buffer_yellow + (tmp1 / eightpdbl);
  1665.     outp_red     = out_buffer_red    + (tmp1 / eightpdbl);
  1666.     outp_blue    = out_buffer_blue   + (tmp1 / eightpdbl);
  1667.     outp_black   = out_buffer_black  + (tmp1 / eightpdbl);
  1668.  
  1669.     /* 360 dpi will be printed interlaced. The interlaced line is after the
  1670.      * first line
  1671.      */
  1672.     if(necp6_opts.dbl && (line % 2) == 1) {
  1673.       outp_yellow += linlen;
  1674.       outp_red    += linlen;
  1675.       outp_blue   += linlen;
  1676.       outp_black  += linlen;
  1677.     }
  1678.  
  1679.     /* processing all pixels of one scan line */
  1680.     for(col = 0; col < pnm_info->width; col++,
  1681.     outp_yellow += necp6_opts.bytes,
  1682.     outp_red    += necp6_opts.bytes,
  1683.     outp_blue   += necp6_opts.bytes,
  1684.     outp_black  += necp6_opts.bytes) {
  1685.  
  1686.       /* reading pixel value */
  1687.       if((*pnm_info->get_pixel_color)(&pixel_yellow, &pixel_red,
  1688.                       &pixel_blue, &pixel_black, in)) {
  1689.     fprintf(stderr, "%s: Can't read pixels from PNM file\n", argv[0]);
  1690.     free(out_buffer_red);
  1691.     free(out_buffer_yellow);
  1692.     free(out_buffer_blue);
  1693.     free(out_buffer_black);
  1694.     NECP6_EXIT(out);
  1695.     return(1);
  1696.       }
  1697.  
  1698.       /* setting pixel in output buffer */
  1699.       if(pixel_yellow)
  1700.     *outp_yellow |= value;
  1701.       if(pixel_red)
  1702.     *outp_red    |= value;
  1703.       if(pixel_blue)
  1704.     *outp_blue   |= value;
  1705.       if(pixel_black)
  1706.     *outp_black  |= value;
  1707.     }
  1708.  
  1709.     /* end of scan line */
  1710.     (*pnm_info->get_pixel_color)(NULL, NULL, NULL, NULL, in);
  1711.   }
  1712.  
  1713.   /* print last buffer */
  1714.   necp6_print_buffer(out, out_buffer_yellow, out_buffer_red,
  1715.              out_buffer_blue, out_buffer_black, linlen,
  1716.              &necp6_opts);
  1717.  
  1718.   /* deinitialization */
  1719.   necp6_print_buffer(out, NULL, NULL, NULL, NULL, 0, &necp6_opts);
  1720.  
  1721.   if(necp6_opts.dbl == 0) {
  1722.     tmp1 *= 2;
  1723.   }
  1724.  
  1725.   switch(necp6_opts.interlace) {
  1726.   case 1:
  1727.     tmp1 -= 24;
  1728.     break;
  1729.   case 2:
  1730.     tmp1 -= 25;
  1731.     break;
  1732.   }
  1733.  
  1734.   if(tmp1 < 0) {
  1735.     tmp1 = 0;
  1736.   }
  1737.  
  1738.   /* Move paper to end of the picture */
  1739.   while(tmp1--) {
  1740.     NECP6_LF(out);
  1741.   }
  1742.  
  1743.   if(necp6_opts.linefeed) {
  1744.     NECP6_LINEFEED_FULL(out);
  1745.   }
  1746.  
  1747.   if(necp6_opts.formfeed) {
  1748.     NECP6_FORMFEED(out);
  1749.   }
  1750.  
  1751.   /* reset printer */
  1752.   if(necp6_opts.reset) {
  1753.     NECP6_EXIT(out);
  1754.   }
  1755.  
  1756.   /* freeing memory */
  1757.   free(out_buffer_red);
  1758.   free(out_buffer_yellow);
  1759.   free(out_buffer_blue);
  1760.   free(out_buffer_black);
  1761.  
  1762.   return(0);
  1763. }
  1764.